Meehai's blog
How to make a self hosted website and blog
2020-01-21
Hello, I am Mihai and for the 2019 end of year I decided to make a small personal webpage & blog, using completely self-hosted technologies (besides DNS). In a nushell, this website is a PHP Content Management System (CMS) written from scratch, using my ISP's public IP address, hosted on a raspberry pi 3b in my bedroom.
For a long time I've wanted to create a personal blog, mostly in order to write various random ideas and publish them somewhere so they don't die for no reason. And since nothing ever gets deleted from the internet, having a self hosted blog seemed like a natural idea. It's also a nice way to force me to work on things, other than my main job, which is Machine Learning research, with focus on Computer Vision and web-based tabular data. I believe that working on various complementary projects helps with the ever increasing pressure that is required at the main job, while also allowing your creative side to take lead and also learning new technologies and skills. Now I know that this reeks of NIH, however I've always enjoyed to idea of writing software from scratch. This is more of a personal mentality that, whenever I develop something, I want to understand as much of the underlying complexity as possible. Of course, it's turtles all the way down, so I always need to keep in check what technologies I want to use or what modules I can reuse. Having this mental map, I can always fit the modules in two categories: The unboxed category is simply stuff that was implemented by me (such as the login module, which is very simple). The boxed category, on the other hand, is software which I know that is implemented by others, I know relatively well what I use it for and I try to not extend its usage beyond that scope. It can be a placeholder for something I might implement in future or it's simply something that is way too different from the main objective that it's simply not worth to redo. These modules are called boxed simply because I try to box their usage and scope as well as possible and hopefully they don't crawl unexpectedly into the main thing. An example of this is jQuery, which is used a lot for the blog's theme and functionality (like the live editing module of writing on this blog).

Live editing the blog post

Note: I know software engineering and engineering in general greatly benefited by reusing previous ideas/implementations and work on top of that. It's the most time-efficient solution, however, at least for my personal projects which aren't used in any serious environment I like to use as little external solutions as possible.
Now that I've bored you with all that personal philosophy, let's get a bit dirty in how this all thing was put together. Basically, I can divide this into 3 parts: the hardware used, the internet side and the software used. First and most important aspect of this project was the ability to self host the website using a Linux capable SBC. Thus, upon investigating a local second hand online marketplace, I ordered a Raspberry PI3 Model B, which offers a Quad Core ARM CPU as well as 1GB of RAM, which I though is more than enough for a basic HTTP server. This may come in contrast to how web is done nowadays, where everybody is using a cloud provider. And perhaps, that even is the saner solution, as you don't have to deal with downtime problems caused by external factors. You pay for the risk mitigation. Consumption wise, according to this link, the power usage of running this 24/7 is somewhere between 24Wh and 86Wh daily, assuming 0% to 100% CPU usage.

The first boot, after installing the web server as well as an early version of the CMS

For the moment, I keep the board plugged into my PC (which is shut down) and I'm connecting to our router's Wi-Fi. This is suboptimal and I will soon buy a small UTP cable as well as keeping it in a power plug. For now, however, this setup works and is stable enough.
Now, I must force you people to visit this blog, hence having a TLD is required. I used this website to purchase this (meehai.xyz) domain. The DNS provider is DreamHost which has a simple enough panel that allows me to redirect the domain to my public IP. One small hiccup I found is that every time my router disconnects (or every N~5 days) my public IP changes, thus I must manually update the IP in DreamHost's panel. I'm looking for solutions about this, either contact my ISP and ask them to give me a static public IP or talk to DreamHost and try to find a way to automate this problem. An automated solution that I think would work nicely is to have a daemon running on the Pi that checks every hour or so the result of http://whatismyip.com and compare to the previous value. If it is indeed changed, to some sort of API call to DreamHost that should do the same thing as me editing manually in their web interface. For now, however, updating it once a week (+few hours downtime due to DNS propagation) is good enough. I used a standard Raspbian Linux OS on top of which I installed the standard Apache 2 and PHP 7 packages. I did a few modifications to the httpd.conf file to point to the root of the CMS and got it running nice and smoothly.

SSH into pi, memory usage and Apache process stats

I added a rule in my ~/.ssh/config file that points to the SSH server on the board. We can see that, with the default GUI disabled it has about 760MB of RAM available, which is probably enough for low usage (unless this gets too popular). The webserver has been up for 5 days, so this means that the board had no hiccups during this period. This is the more interesting part, so to say. Most people when they want to make a blog, they probably use a pre-built solution, like a Wordpress plugin or a hosted site, like Blogger and that makes a lot of sense. However, the purpose of this small project was to get my hands dirty a bit and create from scratch a new CMS (link), with basic functionality. It's still very much work in progress, but the foundation has been set. I will make a new blog post about the internals and decisions behind the CMS, however, here's a small list of features:
  • Headless install script with various defaults
  • Support for themes
  • No Javascript by default. The blog theme however uses jQuery quite heavily for some functionalities, but the backend of the CMS is only written in PHP.
  • SQL database storing for settings and other misc stuff (like blog ids, titles, tags etc.). Two database implementations are supported, MySQL and SQLite, with the later one being used by default.
  • Installable modules with a small API to be implemented allowing easy distribution/configuration (and potential 'marketplace')
  • Basic login & main menu module
  • Basic routes engine (no support for GET/POST routing, just URLs)
The blog is another custom module built on top of the CMS, which is also open source (link). It contains a module class that implements the Module API as well as a theme, that offers various functionalities specific for a blog page. Again, this module will be presented in another post, however a small list of features is this:
  • Add and create new blog pages
  • Make blog posts visible/invisible/hidden (for drafts/unfinished work)
  • Html is used as writing language, which is simple, familiar and very powerful. This can be augmented with inline CSS and javascript, if required.
  • Live editing mode (as seen above)
  • Various jQuery stuff, like the list of sections following you, automatic numbering of sections/subsections
  • Raspberry Pi - ~21EUR
  • 8GB MicroSD - ~4EUR
  • Domain - ~1EUR (first year)
  • Power consumption price / month (according to this and this) - Somewhere between 24Wh and 86Wh daily. The price for 1KWh is about 0.14E.
    • - lower bound: 24*30/1000*0.14 = 0.1E
    • - upper bound: 86*30/1000*0.14 = 0.36E
  • Human cost: ~2 weeks of development for end of year minus the fun :)
Total: ~26E + some for monthly costs (if I haven't computed the values wrong). Conclusion: Worth
Now, of course, the main purpose of this blog post was to see how stable and usable the whole thing is. As I said before I wanted to make a blog for a rather long time. I'll try and post at least once a month, however I don't have any specific topics in head. It could be anything from Computer Science to lifestyle or even traveling reports. I'll try to categorize them in a sane way though. It's gonna be fun.